/**
 * @file ZTraits.h
 * @brief Traits struct/class
 * @author babear.wangz
 * @date 2011-04-06
 */

#ifndef ZST_ZTraits_H
#define ZST_ZTraits_H

#include "ZHashFunctions.h"

/**
 * @class NodeIdHash
 * @brief hash function for node id
 * @brief now we define id type is only uint*_t, uint32_t usually.
 * @author babear.wangz
 * @date 2011-04-06
 */
template <typename NodeIdType> struct NodeIDHash;
template <> struct NodeIDHash <uint32_t> {
    /// Hash function, see ZHashFunctions.h
    static unsigned Hash(uint32_t id)
    {
        return IntHash(id);
    }
    /// empty node id
    static inline uint32_t Empty()
    {
        return -1;
    }
};

/**
 * @class SequenceHash
 * @brief hash functions for sequence, we use char sequence usually
 * @author babear.wangz
 * @date 2011-04-06
 */
template <typename ElemType> struct SequenceHash;
template <> struct SequenceHash<char> {
    static unsigned Hash(char* seq, uint32_t len)
    {
        return SuperStringHash(seq, len);
    }
};

/**
 * @class ZSTBufferSpaceParameter
 * @brief some parameters for space allocations
 * @author babear.wangz
 * @date 2011-04-06
 */
struct ZSTBufferSpaceParameter {
    /// ZSTEdgeBuffer initial space size
    static const uint32_t ZSTEdgeBufferInitSize = 4096;
    /// ZSTEdgeBuffer space extension rate
    static const double ZSTEdgeBufferExtRate = 1.5f;
    /// ZSTEdgeBuffer hash rate
    static const double ZSTEdgeBufferHashRate = 0.8f;

    ///ZSTSequenceBuffer initial space size
    static const uint32_t ZSTSequenceBufferInitSize = 1024;
    ///ZSTSequenceBuffer space extension rate
    static const double ZSTSequenceBufferExtRate = 1.5f;
};

/**
 * @class ZTypeTraits
 * @brief traits for types
 * @author babear.wangz
 * @date 2011-04-06
 */
template <typename T> struct ZTypeTraits;
template <> struct ZTypeTraits<char> {
    // the equal function
    static bool equal(const char& a, const char& b) { return a == b; }
    // whether the T type need to be constructed by replacement new?
    static const bool need_construct = false;
    // empty
    static const char empty = 0;
};

#endif

